package com.daxt.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.daxt.base.common.util.RedisUtil;
import com.daxt.common.result.Result;
import com.daxt.common.result.ResultUtil;
import com.daxt.mapper.archives.ArchivesDocMapper;
import com.daxt.mapper.archives.ArchivesTestingFourMapper;
import com.daxt.mapper.archives.ArchivesTestingFourMetadataMapper;
import com.daxt.mapper.archives.ArchivesTestingFourRecordMapper;
import com.daxt.mapper.sys.DeptMapper;
import com.daxt.model.dic.DicFourSexClassify;
import com.daxt.model.dic.SystemConfigType;
import com.daxt.model.service.accept.vo.WorkOrder;
import com.daxt.model.service.archives.vo.*;
import com.daxt.model.service.base.vo.Dept;
import com.daxt.service.ArchivesTestingFourService;
import com.daxt.utils.BaseUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class ArchivesTestingFourServiceImp extends ServiceImpl<ArchivesTestingFourMapper, ArchivesTestingFour> implements ArchivesTestingFourService {

    @Autowired
    private ArchivesTestingFourMapper archivesTestingFourMapper;
    @Autowired
    private ArchivesTestingFourMetadataMapper archivesTestingFourMetadataMapper;
    @Autowired
    private ArchivesDocMapper archivesDocMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private ArchivesTestingFourRecordMapper archivesTestingFourRecordMapper;

    @Override
    public Result fourDetection(ArchivesDoc doc, WorkOrder workOrder,List<String> listFilePath,String zipPath) {
        List<ArchivesTestingFour> atfList = archivesTestingFourMapper.selectList(new QueryWrapper<ArchivesTestingFour>().eq("source", doc.getSource()));
        if (!BaseUtil.listIsNotNullElement(atfList)) return ResultUtil.error("请检查（四性检测）配置项");
        atfList.forEach((ArchivesTestingFour atf) -> {
            String optionList = atf.getOptionList();
            Map jsonObject = (Map) JSONObject.parse(optionList);

            if (null != jsonObject) {

                for (DicFourSexClassify dfsc : DicFourSexClassify.values()) {

                    Map m = (Map) jsonObject.get(dfsc.getKey());
                    if (null != m) detection(doc, m, dfsc, atf.getTestType(),workOrder,listFilePath,zipPath);
                }
            }
            return;

        });
        return ResultUtil.success();
    }

    /**
     * @description: 四性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detection(ArchivesDoc doc, Map testMap, DicFourSexClassify dic, String testType, WorkOrder workOrder,List<String> listFilePath,String zipPath) {
        String classifyKey = dic.getKey();
        String classifyVal = dic.getValue();
        ArchivesTestingFourRecord atfr = new ArchivesTestingFourRecord();
        testMap.forEach((k, v) -> {

            ArchivesTestingFourMetadata atfm = archivesTestingFourMetadataMapper.selectById(k.toString());
            Object receiveVal = null;
            if (null != atfm) {
                receiveVal = gainClassFieldVal(atfm.getField(), doc);
                atfr.setField(atfm.getField());
            }

            //长度检测
            if (dic == DicFourSexClassify.TYPE_1_1) {
                detectionLength(atfr, receiveVal, v);
            }
            //类型检测
            if (dic == DicFourSexClassify.TYPE_1_2) {
                detectionType(atfr, receiveVal, v);
            }
            //合理性检测
            if (dic == DicFourSexClassify.TYPE_1_3) {
                detectionRationality(atfr, receiveVal, v);
            }
            //特殊字符检测
            if (dic == DicFourSexClassify.TYPE_1_4) {
                detectionSpecialStr(atfr, receiveVal, v);
            }
            //重复性检测
            if (dic == DicFourSexClassify.TYPE_1_5) {
                detectionRepeatability(atfr, receiveVal, atfm.getField());
            }
            //电子文件真实性检测
            if (dic == DicFourSexClassify.TYPE_1_6) {
                detectionContentAuthenticity(atfr, receiveVal, null != atfm ? atfm.getField() : "",workOrder,listFilePath);
            }
            //电子文件 元数据与内容关联一致性
            if (dic == DicFourSexClassify.TYPE_1_7) {
                detectionFileRelevance(atfr, listFilePath,zipPath);
            }
            //基本信息表规范性检测
            if (dic == DicFourSexClassify.TYPE_1_8) {
                detectionBaseStandard(atfr, doc);
            }
            //目录结构规范性检测
            if (dic == DicFourSexClassify.TYPE_1_9) {
                atfr.setTest("true");
            }
            //@TODO 之后的需要补充
            if (dic == DicFourSexClassify.TYPE_3_1) {
                //归档包中元数据可读性检测
                //detectionContentAuthenticity(atfr, receiveVal, null != atfm ? atfm.getField() : "");
            }
            //@TODO 之后的需要补充
            if (dic == DicFourSexClassify.TYPE_4_1) {
                //归档包中多余文件检测
                //detectionContentAuthenticity(atfr, receiveVal, null != atfm ? atfm.getField() : "");
            }


            if (StringUtils.isEmpty(atfr.getTest())) return;

            atfr.setDocId("-1");

            atfr.setTestType(testType);
            atfr.setTestClassify(classifyKey);
            atfr.setCreateTime(LocalDateTime.now());
            atfr.setSource(doc.getSource());

            if (null != atfm) {
                atfr.setDescribes(dic.getValue() + "，" + v.toString() + ":" + atfm.getName() + "," + (atfr.getTest().equals("true") ? "通过" : "不通过"));
            } else {
                atfr.setDescribes(dic.getValue() + "，" + (atfr.getTest().equals("true") ? "通过" : "不通过"));
            }

            archivesTestingFourRecordMapper.insert(atfr);
        });

    }

    /**
     * @description: 四性检测  基本信息表规范性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionBaseStandard(ArchivesTestingFourRecord atfr, ArchivesDoc doc) {
        atfr.setTest("false");

        try {
            //查看字段是否为空
            if("OA".equals(doc.getSource())){
                System.out.println("基本信息:"+doc.toString());
                if(StringUtils.isEmpty(doc.getDutyPeople()))return ; //责任者
                //if(StringUtils.isEmpty(doc.getWritingNum()))return ;//文号
                if(StringUtils.isEmpty(doc.getTitle()))return ;//题名
                if(StringUtils.isEmpty(doc.getSysArchivingTime()))return ;//成文日期
                if(StringUtils.isEmpty(doc.getPages()))return ;//文件页数
                if(StringUtils.isEmpty(doc.getArchivalYear()))return ;//年度
                if(StringUtils.isEmpty(doc.getItemCount()))return ;//文件件数
            }else if ("ZB".equals(doc.getSource())){
                if(StringUtils.isEmpty(doc.getTitle())) return ; //题名
                if(StringUtils.isEmpty(doc.getDutyPeople())) return ; //责任者
                //if(StringUtils.isEmpty(doc.getStoragePeriod())) return ; //保管期限
                //if(StringUtils.isEmpty(doc.getItemName())) return ; //项目名称
                if(StringUtils.isEmpty(doc.getItemCount())) return ; //文件件数
                // 分项工程id
                // 子分项工程id
            }else {
                return ;
            }

            atfr.setTest("true");
            //查看附件信息是否为空
            /*List<AccessoryXml> accessory = doc.getAccessory();
            accessory.forEach((AccessoryXml aXml)->{
                if(StringUtils.isEmpty(aXml.getFileName()))return ;
                if(StringUtils.isEmpty(aXml.getFileFormat()))return ;
                if(StringUtils.isEmpty(aXml.getFileSize()))return ;
            });*/

        } catch (Exception e) {
            e.printStackTrace();
            atfr.setTest("false");
        }

    }

    /**
     * @description: 四性检测  电子文件 元数据与内容关联一致性
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionFileRelevance(ArchivesTestingFourRecord atfr,List<String> listFilePath,String zipPath) {
        atfr.setTest("true");
        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);
        try {
            //判断附件是否存在
            for(int i=0;i<listFilePath.size();i++){
                File file=new File(zipPath+listFilePath.get(i));
                if(!file.exists()) {
                    atfr.setTest("false");
                    break;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            atfr.setTest("false");
        }
    }

    /**
     * @description: 四性检测  电子文件 内容真实性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionContentAuthenticity(ArchivesTestingFourRecord atfr, Object receiveVal, String fieldName, WorkOrder workOrder,List<String> listFilePath) {
        atfr.setTest("false");
        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);

        try {
            //判断附件大小是否正确
            if (fieldName.equals("docTotalSize")) {
                BigDecimal docTotalSize = new BigDecimal(0d);

                File file = new File(workOrder.getSavePath());
                long fLength = file.length();
                //Double i = (fLength / (1024.0 * 1024.0));//MB
                Double i = fLength / 1024.0;//kb
                BigDecimal fileLength = new BigDecimal(i.toString());
                //docTotalSize = docTotalSize.add(fileLength.setScale(1, BigDecimal.ROUND_DOWN));
                docTotalSize = docTotalSize.add(fileLength.setScale(0, BigDecimal.ROUND_HALF_UP));

                receiveVal=receiveVal.toString().toUpperCase();
                String receiveStr = receiveVal.toString().substring(0, receiveVal.toString().indexOf("KB"));
                BigDecimal receiveBig = new BigDecimal(receiveStr);
                System.err.println("附件总大小比较，实际文件大小：" + docTotalSize + "填写文件大小：" + receiveBig);
                int j = docTotalSize.compareTo(receiveBig);
                if (j == 0) atfr.setTest("true");
            }

            //判断附件总数量是否正确
            if (fieldName.equals("itemCount")) {
                if(workOrder.getAppId().equals("ZB")){
                    atfr.setTest("true");
                }else if ((listFilePath.size()) == Integer.parseInt(receiveVal.toString())) {
                    atfr.setTest("true");
                }
                System.out.println("实际总数量："+listFilePath.size()+",填写的数量:"+receiveVal.toString());
            }

            //判断单位名称是否为真
            if (fieldName.equals("dutyCompany")) {
                int count = deptMapper.selectCount(new QueryWrapper<Dept>().eq("deptname",receiveVal.toString()));
                if(count>0) atfr.setTest("true");
            }

            //判断电子文件号
            if (fieldName.equals("itemNum")) {
                atfr.setTest("true");
            }

            //判断归档包类型
            if (fieldName.equals("filingPageType")) {
                atfr.setTest("true");
            }
            //判断归档包标示ID
            if (fieldName.equals("itemCode")) {
                atfr.setTest("true");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @description: 四性检测  重复性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionRepeatability(ArchivesTestingFourRecord atfr, Object receiveVal, String fieldName) {
        String testResult = "false";
        try {

            int i = archivesDocMapper.selectCount(new QueryWrapper<ArchivesDoc>().eq(fieldName, receiveVal));
            if (i <= 0) {
                testResult = "true";
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        atfr.setTest(testResult);


    }

    /**
     * @description: 四性检测  特殊字符检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionSpecialStr(ArchivesTestingFourRecord atfr, Object receiveVal, Object rule) {

        String testResult = "false";
        try {
            String[] rules = rule.toString().split("、");
            for (String ruleStr : rules) {
                if (receiveVal.toString().contains(ruleStr)) {
                    atfr.setTest(testResult);
                    return;
                }
                ;
            }
            testResult = "true";
        } catch (Exception e) {
            e.printStackTrace();
        }
        atfr.setTest(testResult);
    }

    /**
     * @description: 四性检测  合理性检测
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionRationality(ArchivesTestingFourRecord atfr, Object receiveVal, Object rule) {

        String testResult = "false";
        try {
            String[] rules = rule.toString().split(",");
            long ruleStart = Long.parseLong(rules[0]);
            long ruleEnd = Long.parseLong(rules[1]);
            long rValLong = Long.parseLong(receiveVal.toString());

            if (rValLong >= ruleStart && rValLong <= ruleEnd) {
                testResult = "true";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        atfr.setTest(testResult);
    }

    /**
     * @description: 四性检测  检测类型
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionType(ArchivesTestingFourRecord atfr, Object receiveVal, Object v) {
        try {
            if (v.toString().equals("字符型")) {
                receiveVal.toString();
            }
            if (v.toString().equals("数值型")) {
                Double.parseDouble(receiveVal.toString());
            }
            if (v.toString().equals("日期型") || v.toString().equals("日期时间性")) {
                Date d = new Date(receiveVal.toString());
            }
            atfr.setTest("true");
        } catch (Exception e) {
            e.printStackTrace();
            atfr.setTest("false");
        }
    }

    /**
     * @description: 四性检测  检测长度
     * @author: lig
     * @date: 2022/2/24
     */
    private void detectionLength(ArchivesTestingFourRecord atfr, Object val, Object v) {
        atfr.setTest("false");
        try {
            if (val.toString().length() <= Integer.parseInt(v.toString())) {
                atfr.setTest("true");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * @description: 获取class里的属性值
     * @author: lig
     * @date: 2022/2/25
     */
    private Object gainClassFieldVal(String field, Object adr) {
        Object receiveVal = null;
        try {
            // 得到类对象
            Class userCla = (Class) adr.getClass();
            Field fs = userCla.getDeclaredField(field);
            fs.setAccessible(true); // 设置些属性是可以访问的
            receiveVal = fs.get(adr);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return receiveVal;

    }

}
